/*
 * Copyright (C) 2010 LianHaidong <lianhaidong@gmail.com>
 */

#ifndef _UTILS_MEM_POOL_H
#define _UTILS_MEM_POOL_H

#include "utils/list.h"

struct mem_pool;

struct mem_pos {
	struct list_head entry;
	char *alloc_file;
	int alloc_pos;
	char *free_file;
	int free_pos;
};

struct mem_obj {
#ifdef MEM_POOL_DEBUG
	struct list_head pos_list;
#endif
	struct list_head entry;
	struct mem_pool *pool;
	int busy;
	int size_nr;
	uint8_t buf[];
};

struct mem_pool {
#ifdef MEM_POOL_DEBUG
	struct list_head pos_list;
#endif
	struct list_head busy_list;
	struct list_head free_list;
	int busy_count;
	int free_count;
	int size_nr;
};

static inline uint64_t mem_pool_total_size(struct mem_pool *mp)
{
	uint64_t count;

	count = mp->busy_count + mp->free_count;
	return count << (mp->size_nr + 1);
}

static inline uint64_t mem_pool_busy_size(struct mem_pool *mp)
{
	uint64_t count;

	count = mp->busy_count;
	return count << (mp->size_nr + 1);
}

static inline uint64_t mem_pool_free_size(struct mem_pool *mp)
{
	uint64_t count;

	count = mp->free_count;
	return count << (mp->size_nr + 1);
}

#ifdef  MEM_POOL_DEBUG 
struct mem_pool *__mem_pool_create(int max_count, int size, char *file, int line);
#define mem_pool_create(max_count, size)	\
	__mem_pool_create(max_count, size, __FILE__, __LINE__)

int __mem_pool_delete(struct mem_pool *mp, char *file, int line);
#define mem_pool_delete(mp)  __mem_pool_delete(mp, __FILE__, __LINE__)

void *__mem_pool_alloc(struct mem_pool *mp, char *file, int line);
#define mem_pool_alloc(mp) __mem_pool_alloc(mp, __FILE__, __LINE__)

int __mem_pool_free(struct mem_pool *mp, void *mobj, char *file, int line);
#define mem_pool_free(mp, mobj) __mem_pool_free(mp, mobj, __FILE__, __LINE__)

#else

struct mem_pool *mem_pool_create(int max_count, int size);

int mem_pool_delete(struct mem_pool *mp);

void *mem_pool_alloc(struct mem_pool *mp);

int mem_pool_free(struct mem_pool *mp, void *mobj);

#endif	/*  MEM_POOL_DEBUG */

int mem_pool_show_all(struct mem_pool *mp);


#endif	/* _UTILS_MEM_POOL_H */
